#include<fstream>
#include<map>
#include<string>
#include "../LIB/common/packet.h"
#include "../LIB/osocklib/osocklib.h"
#include "../LIB/osocklib/sockstack.h"
#include "../LIB/sspsock/sspsock.h"
#include "../LIB/router/bamrouter.h"

class cFileLoginManager : public BAM::cLoginManager
{
private:
        map<string, string> vMap;

public:
        cFileLoginManager(const char* filename)
        {
                ifstream f(filename);
                if(!f)
                        throw cException("Unable to open password file");
                string login, pass;
                while(!f.eof())
                {
                        f >> login;
                        if(f.eof())
                                throw cException("Wrong password file format");
                        f >> pass;
                        vMap.insert(pair<string, string>(login, pass));
                }
        }

        BAM::cPacket getPassword(const BAM::cPacket &login)
        {
                BAM::cPacket P = login;
                P.insertTail((const BAM::byte*)"", 1);
                map<string, string>::const_iterator it = vMap.find((const char*)P.getData());
                if(it == vMap.end())
                        throw BAM::EXC_Login;
                return BAM::cPacket((const BAM::byte*)(it->second.c_str()), strlen(it->second.c_str()));
        }
};

#ifndef _WIN32
#define stricmp strcasecmp
#endif

int main(int argc, char** argv)
{
        if(argc != 5 && argc != 4)
        {
                cout << "Usage: " << argv[0] << "listening-adderss destination-adderss login|\"none\" [secure]" << endl;
                return 1;
        }
        BAM::cForwarder* fwd = new BAM::cForwarder(argv[2], argv[1]);
        BAM::cRoutersHolder hld;
//        BAM::cTrafficLog tl(&cout, false, false);
        cFileLoginManager lm("passwd");
        if(!stricmp(argv[3], "none"))
                fwd->setSecure(&lm, argc == 5 && !stricmp(argv[4], "secure"), 0, false);
        else
                fwd->setSecure(&lm, argc == 5 && !stricmp(argv[4], "secure"), argv[3], false);
//        fwd->setControler(&tl);
//      fwd->setChildControler(&tl);
        fwd->start();
        hld.add(fwd);
        hld.run();
        return 0;
}
